using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Game.ModbusHepler.Resolve
{

    public enum SendType
    {
        Request,    // 请求
        Response    // 回复
    }

    public enum FunctionCode
    {
        SetFunctionCode10 = 0x10,  // 设置功能码10
        SetFunctionCode06 = 0x06,  // 设置功能码06
        ReadFunctionCode03 = 0x03,  // 读取功能码03
        ReadFunctionCode04 = 0x04,  // 读取功能码04
        ReadFunctionCode20 = 0x20,  // 读取功能码20
        ReadFunctionCode39 = 0x39,  // 读取功能码20
        ReadFunctionCode1e = 0x1e,  // 读取功能码20
    }

    public class ModbusResponse
    {
        public byte DeviceAddress { get; set; } // 设备地址
        public byte FunctionCode { get; set; }  // 功能码
        public byte ByteCount { get; set; }      // 字节数
        public List<ushort> Data { get; set; }   // 数据，多个字节封装成 List<ushort>
        public string CRC { get; set; }          // CRC 校验码

        public ModbusResponse(byte deviceAddress, byte functionCode, byte byteCount, List<ushort> data, string crc)
        {
            DeviceAddress = deviceAddress;
            FunctionCode = functionCode;
            ByteCount = byteCount;
            Data = data;
            CRC = crc;
        }

        public override string ToString()
        {
            return $"设备地址: {DeviceAddress:X2}, " +
                   $"功能码: {FunctionCode:X2}, " +
                   $"字节数: {ByteCount}, " +
                   $"数据: {string.Join(" ", Data)}, " + // 使用 Join 显示 List 中的所有项
                   $"CRC: {CRC}";
        }
        // 高低位转换
        private static ushort SwapBytes(ushort value)
        {
            return (ushort)((value >> 8) | (value << 8));
        }
        // 从字节数组初始化 ModbusResponse
        public static ModbusResponse FromByteArray(byte[] response)
        {
            if (response.Length < 5) // 确保数组长度足够
                throw new ArgumentException("Invalid response length.");

            byte deviceAddress = response[0]; // 设备地址
            byte functionCode = response[1];   // 功能码
            byte byteCount = response[2];       // 字节数
            byte[] rawData = new byte[byteCount]; // 原始字节数据数组

            Array.Copy(response, 3, rawData, 0, byteCount); // 复制数据

            // 封装字节数据为 List<ushort>
            List<ushort> data = new List<ushort>();
            for (int i = 0; i < byteCount; i += 2)
            {
                if (i + 1 < byteCount) // 确保能读取成 ushort
                {
                    ushort value = SwapBytes(BitConverter.ToUInt16(rawData, i));
                    data.Add(value);
                }
            }

            string crc = BitConverter.ToString(response, 3 + byteCount).Replace("-", ""); // CRC 校验码

            return new ModbusResponse(deviceAddress, functionCode, byteCount, data, crc);
        }
    }
    public class ModbusRequest
    {
        public byte DeviceAddress { get; set; } // 设备地址
        public byte FunctionCode { get; set; }  // 功能码
        public ushort RegisterAddress { get; set; } // 寄存器地址
        public ushort WriteValue { get; set; } // 写入值，两个字节
        public string CRC { get; set; } // CRC 校验码

        public ModbusRequest(byte deviceAddress, byte functionCode, ushort registerAddress, ushort writeValue, string crc)
        {
            DeviceAddress = deviceAddress;
            FunctionCode = functionCode;
            RegisterAddress = registerAddress;
            WriteValue = writeValue;
            CRC = crc;
        }

        public override string ToString()
        {
            return $"设备地址: {DeviceAddress:X2}, " +
                   $"功能码: {FunctionCode:X2}, " +
                   $"寄存器地址: {RegisterAddress:X4}, " +
                   $"写入值: {WriteValue:X4}, " +
                   $"CRC: {CRC}";
        }

        // 从字节数组初始化 ModbusRequest
        public static ModbusRequest FromByteArray(byte[] request)
        {
            if (request.Length < 8) // 确保数组长度足够，写入值和 CRC 占用额外字节
                throw new ArgumentException("Invalid request length.");

            byte deviceAddress = request[0]; // 设备地址
            byte functionCode = request[1];   // 功能码
            ushort registerAddress = SwapBytes(BitConverter.ToUInt16(request, 2)); // 寄存器地址（高低位转换）
            ushort writeValue = SwapBytes(BitConverter.ToUInt16(request, 4)); // 写入值（高低位转换）
            string crc = BitConverter.ToString(request, 6).Replace("-", ""); // CRC 校验码

            return new ModbusRequest(deviceAddress, functionCode, registerAddress, writeValue, crc);
        }

        // 高低位转换
        private static ushort SwapBytes(ushort value)
        {
            return (ushort)((value >> 8) | (value << 8));
        }
    }
    public class ModbusSetResponse
    {
        public byte DeviceAddress { get; set; } // 设备地址
        public byte FunctionCode { get; set; }  // 功能码
        public ushort RegisterAddress { get; set; } // 寄存器地址
        public ushort RegisterCount { get; set; } // 寄存器数量（占两个字节）
        public string CRC { get; set; } // CRC 校验码

        public ModbusSetResponse(byte deviceAddress, byte functionCode, ushort registerAddress, ushort registerCount, string crc)
        {
            DeviceAddress = deviceAddress;
            FunctionCode = functionCode;
            RegisterAddress = registerAddress;
            RegisterCount = registerCount;
            CRC = crc;
        }

        public override string ToString()
        {
            return $"设备地址: {DeviceAddress:X2}, " +
                   $"功能码: {FunctionCode:X2}, " +
                   $"寄存器地址: {RegisterAddress:X4}, " +
                   $"寄存器数量: {RegisterCount}, " +
                   $"CRC: {CRC}";
        }

        // 从字节数组初始化 ModbusSetResponse
        public static ModbusSetResponse FromByteArray(byte[] response)
        {
            if (response.Length < 8) // 更新检查长度以确保包含寄存器数量的两个字节
                throw new ArgumentException("Invalid response length.");

            byte deviceAddress = response[0]; // 设备地址
            byte functionCode = response[1];   // 功能码
            ushort registerAddress = SwapBytes(BitConverter.ToUInt16(response, 2)); // 寄存器地址（高低位转换）
            ushort registerCount = SwapBytes(BitConverter.ToUInt16(response, 4)); // 寄存器数量（高低位转换）
            string crc = BitConverter.ToString(response, 6).Replace("-", ""); // CRC 校验码

            return new ModbusSetResponse(deviceAddress, functionCode, registerAddress, registerCount, crc);
        }

        // 高低位转换
        private static ushort SwapBytes(ushort value)
        {
            return (ushort)((value >> 8) | (value << 8));
        }
    }
    public class ModbusWrite10Request
    {
        public byte DeviceAddress { get; set; } // 设备地址
        public byte FunctionCode { get; set; }  // 功能码
        public ushort RegisterAddress { get; set; } // 寄存器地址
        public ushort RegisterCount { get; set; } // 寄存器数量
        public byte ByteCount { get; set; } // 字节数
        public byte[] Data { get; set; } // 数据
        public string CRC { get; set; } // CRC

        public ModbusWrite10Request(byte deviceAddress, byte functionCode, ushort registerAddress,
                                 ushort registerCount, byte byteCount, byte[] data, string crc)
        {
            DeviceAddress = deviceAddress;
            FunctionCode = functionCode;
            RegisterAddress = registerAddress;
            RegisterCount = registerCount;
            ByteCount = byteCount;
            Data = data;
            CRC = crc;
        }

        public override string ToString()
        {
            return $"Device Address: {DeviceAddress:X2}, " +
                   $"Function Code: {FunctionCode:X2}, " +
                   $"Register Address: {RegisterAddress:X4}, " +
                   $"Register Count: {RegisterCount}, " +
                   $"Byte Count: {ByteCount}, " +
                   $"Data: {BitConverter.ToString(Data).Replace("-", "")}, " +
                   $"CRC: {CRC}";
        }
    }
    public class ModbusAnalysisHelper
    {
        // 高低位转换
        public static ushort SwapBytes(ushort value)
        {
            return (ushort)((value >> 8) | (value << 8));
        }

        public static ModbusSetResponse SetResponse(byte[] responseMessage)
        {
            // 从字节数组创建 ModbusResponse 对象
            ModbusSetResponse responseSet = ModbusSetResponse.FromByteArray(responseMessage);
            // 输出解析结果
            return responseSet;
        }

        public static ModbusResponse ReadRespond(byte[] responseMessage03)
        {
            // 从字节数组创建 ModbusResponse 对象
            ModbusResponse response03 = ModbusResponse.FromByteArray(responseMessage03);
            return response03;
        }

        public static string UniformRequestBytes(byte[] requestMessage)
        {
            // 从字节数组创建 ModbusWriteRequest 对象
            ModbusRequest writeRequest = ModbusRequest.FromByteArray(requestMessage);
            // 输出解析结果

            return writeRequest.ToString();
        }

        public static ModbusRequest UniformRequestBytesWithObj(byte[] requestMessage)
        {
            // 从字节数组创建 ModbusWriteRequest 对象
            ModbusRequest writeRequest = ModbusRequest.FromByteArray(requestMessage);
            // 输出解析结果

            return writeRequest;
        }

        public static string Set10(byte[] message)
        {
            // 解析报文内容
            byte deviceAddress = message[0]; // 设备地址
            byte functionCode = message[1];   // 功能码
            ushort registerAddress = SwapBytes(BitConverter.ToUInt16(message, 2)); // 寄存器地址 (字节 3 和 4)
            ushort registerCount = SwapBytes(BitConverter.ToUInt16(message, 4));   // 寄存器数量 (字节 5 和 6)
            byte byteCount = message[6];       // 字节数
            byte[] data = new byte[byteCount]; // 数据

            // 复制到数据数组
            Array.Copy(message, 7, data, 0, byteCount); // 从字节 7 开始复制数据
            string crc = BitConverter.ToString(message, 7 + byteCount).Replace("-", ""); // CRC 校验码
            
            return $"设备地址: {deviceAddress:X2},功能码: {functionCode:X2},寄存器地址: {registerAddress:X4},寄存器数量: {registerCount},字节数: {byteCount},数据: {BitConverter.ToString(data).Replace("-", "")},CRC: {crc}";
        }

        public static string ProcessModbusMessage(byte[] message, SendType sendType)
        {
            // 功能码
            FunctionCode functionCode = (FunctionCode)message[1];

            if (sendType == SendType.Request)
            {
                // 处理请求
                switch (functionCode)
                {
                    case FunctionCode.SetFunctionCode10: // 功能码 10
                        return ModbusAnalysisHelper.Set10(message);
                    case FunctionCode.ReadFunctionCode20: // 功能码 20
                    case FunctionCode.ReadFunctionCode03: // 功能码 03
                    case FunctionCode.ReadFunctionCode04: // 功能码 04
                    case FunctionCode.SetFunctionCode06:   // 功能码 06
                        return ModbusAnalysisHelper.UniformRequestBytes(message);
                    default:
                        return ("未知的回复功能码");
                }
            }
            else
            {
                // 处理回复
                switch (functionCode)
                {
                    case FunctionCode.ReadFunctionCode03: // 功能码 03
                    case FunctionCode.ReadFunctionCode04: // 功能码 04
                        var t = ModbusAnalysisHelper.ReadRespond(message);
                        return t.ToString();

                    case FunctionCode.SetFunctionCode10:   // 功能码 10
                        return ModbusAnalysisHelper.SetResponse(message).ToString();
                    case FunctionCode.SetFunctionCode06:   // 功能码 06
                        return ModbusAnalysisHelper.UniformRequestBytes(message);

                    default:
                        return ("未知的回复功能码");
                }
            }
        }

        public static object ProcessModbusMessageWithObj(byte[] message, SendType sendType)
        {
            // 功能码
            FunctionCode functionCode = (FunctionCode)message[1];

            if (sendType == SendType.Request)
            {
                // 处理请求
                switch (functionCode)
                {
                    case FunctionCode.SetFunctionCode10: // 功能码 10
                        return ModbusAnalysisHelper.Set10(message);
                    case FunctionCode.ReadFunctionCode20: // 功能码 20
                    case FunctionCode.ReadFunctionCode1e: // 功能码 20
                    case FunctionCode.ReadFunctionCode03: // 功能码 03
                    case FunctionCode.ReadFunctionCode04: // 功能码 04
                    case FunctionCode.SetFunctionCode06:   // 功能码 06
                    case FunctionCode.ReadFunctionCode39:   // 功能码 39
                        return ModbusAnalysisHelper.UniformRequestBytes(message);
                    default:
                        return ("未知的回复功能码");
                }
            }
            else
            {
                // 处理回复
                switch (functionCode)
                {
                    case FunctionCode.ReadFunctionCode03: // 功能码 03
                    case FunctionCode.ReadFunctionCode04: // 功能码 04
                    case FunctionCode.ReadFunctionCode39: // 功能码 39
                    case FunctionCode.ReadFunctionCode20: // 功能码 20
                    case FunctionCode.ReadFunctionCode1e: // 功能码 20

                        var t = ModbusAnalysisHelper.ReadRespond(message);
                        return t;

                    case FunctionCode.SetFunctionCode10:   // 功能码 10
                        return ModbusAnalysisHelper.SetResponse(message);
                    case FunctionCode.SetFunctionCode06:   // 功能码 06
                        return ModbusAnalysisHelper.UniformRequestBytesWithObj(message);

                    default:
                        return ("未知的回复功能码");
                }
            }

        }

    }
}
